#include "GraphicsView.h"
#include "MainFrame.h"

FCUIView::FCUIView(){
    m_graphicsView = 0;
}

FCUIView::~FCUIView(){
    m_graphicsView = 0;
}


QRectF FCUIView::boundingRect() const{
    QRectF rect(0, 0, m_graphicsView->width(), m_graphicsView->height());
    return rect;
}

void FCUIView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    m_graphicsView->paint(painter);
}

FCGraphicsView::FCGraphicsView(){
    m_objectItem = 0;
    m_host = 0;
    m_native = 0;
    m_paint = 0;
    m_scaleFactor = 0.5;
    m_buttons = 0;
    m_clicks = 0;
    m_textBox = 0;
    m_editingTextBox = 0;
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

FCGraphicsView::~FCGraphicsView(){
    m_objectItem = 0;
    if(m_native){
        delete m_native;
        m_native = 0;
    }
    m_textBox = 0;
    m_editingTextBox = 0;
    m_host = 0;
    m_paint = 0;
}

void FCGraphicsView::paint(QPainter *painter){
    m_paint->m_qPainter = painter;
    FCSize clientSize = {width(), height()};
    resetScaleSize(clientSize);
    FCRect drawRect = {0, 0, (int)((width()) * m_scaleFactor), (int)((height()) * m_scaleFactor)};
    m_host->onPaint(drawRect);
}

void FCGraphicsView::mousePressEvent(QMouseEvent *event){
    FCPoint mp = {event->pos().x(), event->pos().y()};
    m_host->setTouchPoint(mp);
    FCTouchInfo newTouchInfo;
    if(event->button() == 1){
        newTouchInfo.m_firstTouch = true;
    }else if(event->button() == 2){
        newTouchInfo.m_secondTouch = true;
    }
    newTouchInfo.m_buttons = event->button();
    newTouchInfo.m_clicks = 1;
    FCView *lastFocusedView = m_native->getFocusedView();
    m_native->onTouchDown(newTouchInfo);
    FCView *focusedView = m_native->getFocusedView();
    if(dynamic_cast<FCTextBox*>(focusedView)){
        showTextBox(focusedView, lastFocusedView);
    }
    else{
        hideTextBox(focusedView);
    }
    m_buttons = newTouchInfo.m_buttons;
    m_clicks = newTouchInfo.m_clicks;
}

void FCGraphicsView::mouseReleaseEvent(QMouseEvent *event) {
    FCPoint mp = {event->pos().x(), event->pos().y()};
    m_host->setTouchPoint(mp);
    FCTouchInfo newTouchInfo;
    if(m_buttons == 1){
        newTouchInfo.m_firstTouch = true;
    }else if(m_buttons == 2){
        newTouchInfo.m_secondTouch = true;
    }
    newTouchInfo.m_buttons = m_buttons;
    newTouchInfo.m_clicks = m_clicks;
    m_native->onTouchUp(newTouchInfo);
    m_buttons = 0;
    m_clicks = 0;
}

void FCGraphicsView::mouseMoveEvent(QMouseEvent *event){
    FCPoint mp = {event->pos().x(), event->pos().y()};
    m_host->setTouchPoint(mp);
    FCTouchInfo newTouchInfo;
    if(m_buttons == 1){
        newTouchInfo.m_firstTouch = true;
        newTouchInfo.m_clicks = 1;
    }else if(m_buttons == 2){
        newTouchInfo.m_secondTouch = true;
        newTouchInfo.m_clicks = 1;
    }
    newTouchInfo.m_buttons = m_buttons;
    m_native->onTouchMove(newTouchInfo);
}

void FCGraphicsView::mouseDoubleClickEvent(QMouseEvent *event){
    FCPoint mp = {event->pos().x(), event->pos().y()};
    m_host->setTouchPoint(mp);
    FCTouchInfo newTouchInfo;
    if(event->button() == 1){
        newTouchInfo.m_firstTouch = true;
    }else if(event->button() == 2){
        newTouchInfo.m_secondTouch = true;
    }
    newTouchInfo.m_buttons = event->button();
    newTouchInfo.m_clicks = 2;
    m_native->onTouchDown(newTouchInfo);
    m_native->onTouchUp(newTouchInfo);
    m_buttons = 0;
    m_clicks = 0;
}

void FCGraphicsView::keyPressEvent(QKeyEvent *event){
    m_native->onKeyDown(event->key());
    m_native->onChar(event->key());
}

void FCGraphicsView::keyReleaseEvent(QKeyEvent *event){
    m_native->onKeyUp(event->key());
}

void FCGraphicsView::wheelEvent(QWheelEvent *event){
    FCPoint mp = {event->pos().x(), event->pos().y()};
    m_host->setTouchPoint(mp);
    FCTouchInfo newTouchInfo;
    newTouchInfo.m_delta = event->angleDelta().y();
    m_native->onTouchWheel(newTouchInfo);
}

void FCGraphicsView::onLoad(){
    setMouseTracking(true);
    m_native = new FCNative;
    QString appDir = QApplication::applicationDirPath();
    String appPath = appDir.toStdWString().c_str();
    appPath = FCTran::replace(appPath, L"\\", L"/");
    m_native->setResourcePath(appPath + L"/");
    m_paint = new QtPaint();
    m_native->setPaint(m_paint);
    QtHost *host = new QtHost;
    m_host = host;
    host->m_widget = this;
    host->m_objectItem = m_objectItem;
    host->setNative(m_native);
    m_native->setHost(host);
    FCSize tSize = {width(), height()};
    m_native->setSize(tSize);
    m_native->setAllowScaleSize(true);
    resetScaleSize(tSize);
    MainFrame *mainFrame = new MainFrame;
    mainFrame->setNative(m_native);
    mainFrame->loadFile(appPath + L"/MainFrame2.xml", 0);
    m_textBox = new QLineEdit("", this);
    m_textBox->setVisible(false);
}

void FCGraphicsView::resetScaleSize(FCSize clientSize){
    FCSize nativeSize = m_native->getSize();
    FCSize sSize = {(int)(clientSize.cx * m_scaleFactor), (int)(clientSize.cy * m_scaleFactor)};
    FCSize scaleSize = m_native->getScaleSize();
    if(sSize.cx != scaleSize.cx || sSize.cy != scaleSize.cy){
        m_native->setScaleSize(sSize);
        m_native->update();
    }
}

void FCGraphicsView::showTextBox(FCView *view, FCView *lastView){
    if (m_textBox && m_editingTextBox){
        if (lastView && lastView != view && dynamic_cast<FCTextBox*>(lastView)){
            lastView->setText(m_textBox->text().toStdWString().c_str());
            lastView->invalidate();
        }
    }
    m_editingTextBox = view;
    int clX = m_native->clientX(view);
    int clY = m_native->clientY(view);
    double scaleFactorX = 0, scaleFactorY = 0;
    m_paint->getScaleFactor(&scaleFactorX, &scaleFactorY);
    m_textBox->setGeometry(clX * scaleFactorX, clY * scaleFactorY, view->getWidth() * scaleFactorX, view->getHeight() * scaleFactorY);
    m_textBox->setText(QtPaint::toQString(view->getText()));
    FCFont *font = view->getFont();
    String fontFamily = font->m_fontFamily;
    if (fontFamily == L"Default"){
        fontFamily = MyColor::getSystemFont();
    }
    float fontSize = font->m_fontSize;
    if (scaleFactorX != 1 || scaleFactorY != 1){
        fontSize = min(scaleFactorX, scaleFactorY) * fontSize;
    }
    QFont qFont(QtPaint::toQString(fontFamily), fontSize / 2.5);
    m_textBox->setFont(qFont);
    m_textBox->setStyleSheet("QLineEdit {color:"
                             + QtPaint::toQString(FCTran::colorToStr(m_paint->getPaintColor(view->getTextColor())))
                             + "; background-color:" +
                             QtPaint::toQString(FCTran::colorToStr(m_paint->getPaintColor(view->getBackColor()))) +
                             ";border: 1px solid " +
                             QtPaint::toQString(FCTran::colorToStr(m_paint->getPaintColor(view->getBorderColor()))) + ";}");
    m_textBox->setVisible(true);
    m_textBox->setFocus();
}

void FCGraphicsView::hideTextBox(FCView *view){
    if(m_textBox && m_editingTextBox){
        m_editingTextBox->setText(m_textBox->text().toStdWString().c_str());
        m_textBox->setVisible(false);
        m_editingTextBox = 0;
        m_native->invalidate();
    }
}
